local GameWorld = {}

local Grid = require('scripts.models.Grid')
local Player = require('scripts.models.Player')
local GameConstants = require('scripts.GameConstants')

function GameWorld:new(gravity, levelConfig)--player, grid, gravity)
   gameWorld =  display.newGroup()
   gameWorld.gravity = gravity

   --Logical attributes
   gameWorld.activeTimers = {}
   gameWorld.objects = {}
   gameWorld.clear = false
   gameWorld.time = 0--seconds
   gameWorld.goal  = levelConfig.goal
   gameWorld.hauntTimer = 12

   -- player
   gameWorld.player = Player:new(
      gameWorld.gravity,
      levelConfig['levelWidth'] * levelConfig.start.col - 20,
      levelConfig['levelHeight'] * levelConfig.start.row - 20
   )
   gameWorld.player:centerCamera(gameWorld)

   -- grid
   gameWorld.grid = Grid:new(
      levelConfig['rows'],
      levelConfig['cols'],
      levelConfig['levelWidth'],
      levelConfig['levelHeight'],
      levelConfig['structure']
   )

   local knights = levelConfig.knights
   orcs = levelConfig.orcs
   gameWorld:insert(gameWorld.grid)

   local spriteSheetInfoAreas = require('resources.sprites.atlasses.areas-hd')
   local spriteSheetAreas     = graphics.newImageSheet("resources/sprites/atlasses/areas-hd.png", spriteSheetInfoAreas:getSheet())
   -- print (#knights)
   for i = 1, #knights do
   	-- print 'here'
   	local k = display.newImage(spriteSheetAreas, spriteSheetInfoAreas:getFrameIndex('area2-1'))

   	k:scale(0.2, 0.2)
   	k.x = knights[i].col * levelConfig['levelWidth'] - k.contentWidth * 0.5
   	k.y = knights[i].row * levelConfig['levelHeight'] - k.contentHeight  * 0.7
   	gameWorld:insert(k)
   end
   for i= 1, #orcs do
   	-- print 'here'
   	local o = display.newImage(spriteSheetAreas, spriteSheetInfoAreas:getFrameIndex('area1-1'))

   	o:scale(0.2, 0.2)
   	o.x = orcs[i].col * levelConfig['levelWidth'] - o.contentWidth * 0.5
   	o.y = orcs[i].row * levelConfig['levelHeight'] - o.contentHeight * 0.7
   	gameWorld:insert(o)
   end
   gameWorld:insert(gameWorld.player)

   function gameWorld:drawGoal()
      local x, y = levelConfig['levelWidth'] * levelConfig.goal.col, levelConfig['levelHeight'] * levelConfig.goal.row
      local goal = display.newImageRect( "resources/sprites/goal.png", X*0.27, Y*0.188 )
      goal.x = x
      goal.y = y
      gameWorld:insert(goal)

      -- local CBE = require("CBEffects.Library")
      -- local vent = CBE.newVent {
      --    preset = "burn"
      -- }
      -- local function onScreenTouch(event)
      --    vent.x, vent.y = event.x, event.y -- We want the vent to move no matter what the phase of the event

      --    if "began" == event.phase then
      --       vent:start() -- Start if began
      --    elseif "ended" == event.phase then
      --       vent:stop() -- Stop if ended
      --    end
      -- end
      -- Runtime:addEventListener("touch", onScreenTouch)
   end

   function gameWorld:startDeath()
      local hideTiles = self.player:playDead()
      logger:debug(hideTiles)
      if hideTiles then
         self.grid:insert(self.player)

         local playerX,playerY = self.player:getReferencePos()
         local cell = self.grid:getCellFromCoordinates(playerX,playerY)
         local row,column = cell.gridRow,cell.gridCol

         for i=row+1,self.grid.rows do
            self.grid.cells[i][cell.gridCol]:toFront()
            self.grid.cells[i][cell.gridCol-1]:toFront()
            self.grid.cells[i][cell.gridCol+1]:toFront()
         end
      end
   end

   function gameWorld:update(delta)
      self.time = self.time + delta

      --logger:debug(self.player.sprite.sequence)

      local playerX,playerY = self.player:getReferencePos()
      local cell = self.grid:getCellFromCoordinates(playerX,playerY)
      if cell then
      	-- print (cell.gridRow, cell.gridCol, self.goal.row, self.goal.col)
         if cell.gridRow == self.goal.row and cell.gridCol == self.goal.col then
            self:clearStage()
         else
           cell:modifyPlayerState(self.player, delta)
         end
      else
         self.player:damagePlayer(1000000,1)
      end
      self.player:update(delta)

      gameWorld.hauntTimer = gameWorld.hauntTimer - delta
      if(gameWorld.hauntTimer < 0) then
         self.haunt()
         gameWorld.hauntTimer = math.random(20)
      end

   end
   function gameWorld:haunt()
      local playerRemainingLife = gameWorld.player.life
      local thisHaunt = math.random(#haunts)
      if(playerRemainingLife < 25) then
         audio.play(haunts[4],{channel=5})
      else
         audio.play(haunts[thisHaunt],{channel=5})
      end

   end
   function gameWorld:isClear()
   		return gameWorld.clear
   end
   function gameWorld:clearStage()
   		gameWorld.clear = true
   end
   function gameWorld:insertObject(object)
      table.insert(gameWorld.objects, object)
   end

   function gameWorld:insertCircle(circle)
      self.circle = circle
   end

   function gameWorld:getTotalScore()
      local timeTotal =  math.round(60*3 - self.time)
      local playerLife = self.player.life
      local totalScore = timeTotal + timeTotal * playerLife * 0.01

      print("totalScore ", totalScore )
      return totalScore
   end

   gameWorld:drawGoal()

   return gameWorld
end

return GameWorld